ah, sorry for taking so long to reply; heres my code:
.cpp file:
#include "Box2dShadowEngine.h"
#include "GLOBAL.h"
using namespace std;
//Light struct
Light::Light(void)
{
}
Light::Light(float x, float y, float Radius)
{
centre.x = x;
centre.y = y;
radius = Radius;
}
void Light::SetColour(float Red, float Green, float Blue, float Brightness)
{
red = Red;
green = Green;
blue = Blue;
brightness = Brightness;
}
void Light::Move(float x, float y)
{
centre.x = x;
centre.y = y;
}
void Light::Resize(float Radius)
{
radius = Radius;
}
//Shadow engine class
Box2dShadowEngine::Box2dShadowEngine(void)
{
}
Box2dShadowEngine::~Box2dShadowEngine(void)
{
}
void Box2dShadowEngine::AddLight(Light aLight)
{
LightList.push_back(aLight);
}
void Box2dShadowEngine::PrintLightList(void)
{
Light OLight;
for(unsigned int i = 0;i<LightList.size();i++)
{
OLight = LightList[i];
printf("Light:%i\n",i);
printf(" Red:%f\n",OLight.red);
printf(" Green:%f\n",OLight.green);
printf(" Blue:%f\n",OLight.blue);
printf(" Brightness:%f\n",OLight.brightness);
printf(" Radius:%f\n",OLight.radius);
printf(" Centre:X:%f Y:%f\n",OLight.centre.x,OLight.centre.y);
}
}
void Box2dShadowEngine::RenderLights(void)
{
Light OLight;
float radius, red, green, blue, brightness;
b2Vec2 centre;
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for(unsigned int i = 0;i<LightList.size();i++)
{
OLight = LightList[i];
radius = OLight.radius;
red = OLight.red;
green = OLight.green;
blue = OLight.blue;
brightness = OLight.brightness;
centre = OLight.centre;
b2Vec2 POINT(0,radius);
glBegin(GL_TRIANGLE_FAN);
glColor4f(red,green,blue,brightness);
glVertex3f(centre.x,centre.y,0.0);
glColor4f(red,green,blue,0.0);
for(float x = 0;x<M_PI*2;x+=M_PI/20)
{
b2Vec2 C1( -sin(x),cos(x));
b2Vec2 C2(cos(x),sin(x));
b2Mat22 ROTMATRIX(C2,C1);
b2Vec2 rPOINT = b2Mul(ROTMATRIX,POINT);
rPOINT = rPOINT+centre;
glVertex3f(rPOINT.x,rPOINT.y,0.0);
}
b2Vec2 C1( -sin(0.0),cos(0.0));
b2Vec2 C2(cos(0.0),sin(0.0));
b2Mat22 ROTMATRIX(C2,C1);
b2Vec2 rPOINT = b2Mul(ROTMATRIX,POINT);
rPOINT = rPOINT+centre;
glVertex3f(rPOINT.x,rPOINT.y,0.0);
glColor4f(red,green,blue,brightness);
glVertex3f(centre.x,centre.y,0.0);
glEnd();
}
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void Box2dShadowEngine::RenderShadows(void)
{
glColor4f(0.0,0.0,0.0,0.1);
glBegin(GL_POLYGON);
glVertex3f(-1000,-1000,0.0);
glVertex3f(1000,-1000,0.0);
glVertex3f(1000,1000,0.0);
glVertex3f(-1000,1000,0.0);
glEnd();
for(unsigned int i = 0;i<LightList.size();i++)
{
Light CLight = LightList[i];
for (b2Body* b = ShadowEngineWorld->GetBodyList(); b; b = b->GetNext())
{
b2Fixture* GetFixtureList();
for (b2Fixture* f = b->GetFixtureList(); f; f = f->GetNext())
{
b2Shape* s = f->GetShape();
b2ShapeType SHAPETYPE = s->GetType();
if(SHAPETYPE == -1){
//printf(" Unknown Shape\n");
}
if(SHAPETYPE == 0){
//b2CircleShape* c = (b2CircleShape*)s;
//printf(" Circle Shape shadow\n");
}
if(SHAPETYPE == 1){
b2PolygonShape* p = (b2PolygonShape*)s;
RenderPolygonShadow(p,b,CLight);
//printf(" Polygon Shape shadow\n");
}
if(SHAPETYPE == 2){
b2EdgeShape* e = (b2EdgeShape*)s;
RenderLineShadow(e,b,CLight);
//printf("static shape shadow\n");
}
if(SHAPETYPE == 3){
//printf("unknown shape error!\n");
}
}
}
}
}
void Box2dShadowEngine::RenderPolygonShadow(b2PolygonShape* p,b2Body* b,Light CLight)
{
bool Facing;
bool PrevFacing;
b2Vec2 sbv1(0,0);
b2Vec2 sbv2(0,0);
b2Vec2 ssv1(0,0);
b2Vec2 ssv2(0,0);
for(int i = 0;i<p->GetVertexCount();i++)
{
float angle = b->GetAngle();
//creating a Rotation Matrix
//Top Row
b2Vec2 C1( -sin(angle),cos(angle));
//Bottom Row
b2Vec2 C2(cos(angle),sin(angle));
//Put it together
b2Mat22 ROTMATRIX(C2,C1);
b2Vec2 FaceVert1 = p->GetVertex(i);
b2Vec2 FaceVert2;
//printf("%i\n",i);
if(i == p->GetVertexCount()-1)
{
FaceVert2 = p->GetVertex(0);
}else{
FaceVert2 = p->GetVertex(i+1);
}
FaceVert1 = b2Mul(ROTMATRIX,FaceVert1)+b->GetWorldCenter();
FaceVert2 = b2Mul(ROTMATRIX,FaceVert2)+b->GetWorldCenter();
b2Vec2 Normal(FaceVert1.x-FaceVert2.x,FaceVert1.y-FaceVert2.y);
b2Vec2 nC1(0,1);
b2Vec2 nC2(-1,0);
b2Mat22 nROTMATRIX(nC1,nC2);
Normal = b2Mul(nROTMATRIX,Normal);
b2Vec2 Midpoint = (FaceVert2+FaceVert1);
Midpoint.x = Midpoint.x/2;Midpoint.y = Midpoint.y/2;
b2Vec2 VecToLight = CLight.centre-Midpoint;
{
float DotProd = b2Dot(Normal, VecToLight);
if(DotProd>0)
{
Facing = true;
if(DebugMode==true){
glColor4f(1.0,0.0,0.0,0.2);
glBegin(GL_POLYGON);
glVertex3f(Midpoint.x+0.5,Midpoint.y+0.5,0.0);
glVertex3f(Midpoint.x-0.5,Midpoint.y+0.5,0.0);
glVertex3f(Midpoint.x-0.5,Midpoint.y-0.5,0.0);
glVertex3f(Midpoint.x+0.5,Midpoint.y-0.5,0.0);
glEnd();
}
}else{
Facing = false;
{
b2Vec2 V1vtl = 100*(FaceVert1-CLight.centre);
b2Vec2 V2vtl = 100*(FaceVert2-CLight.centre);
if(DebugMode == true)
{
glBegin(GL_LINES);
glVertex3f(FaceVert1.x,FaceVert1.y,0.0);
glVertex3f(FaceVert1.x+V1vtl.x,FaceVert1.y+V1vtl.y,0.0);
glVertex3f(FaceVert2.x,FaceVert2.y,0.0);
glVertex3f(FaceVert2.x+V2vtl.x,FaceVert2.y+V2vtl.y,0.0);
glEnd();
}
glBlendFunc(GL_ZERO, GL_ZERO);
glBegin(GL_POLYGON);
glColor4f(0.0,0.0,0.0,1.0);
glVertex3f(FaceVert1.x,FaceVert1.y,0.0);
glVertex3f(FaceVert2.x,FaceVert2.y,0.0);
glVertex3f(FaceVert2.x+V2vtl.x,FaceVert2.y+V2vtl.y,0.0);
glVertex3f(FaceVert1.x+V1vtl.x,FaceVert1.y+V1vtl.y,0.0);
glEnd();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
if(DebugMode== true)
{
glColor4f(0.0,1.0,0.0,0.2);
glBegin(GL_POLYGON);
glVertex3f(Midpoint.x+0.5,Midpoint.y+0.5,0.0);
glVertex3f(Midpoint.x-0.5,Midpoint.y+0.5,0.0);
glVertex3f(Midpoint.x-0.5,Midpoint.y-0.5,0.0);
glVertex3f(Midpoint.x+0.5,Midpoint.y-0.5,0.0);
glEnd();
}
}
}
}
PrevFacing = Facing;
}
}
void Box2dShadowEngine::RenderLineShadow(b2EdgeShape* e,b2Body* b, Light CLight)
{
//get end points and then cast shadow. YAY!;
float angle = b->GetAngle();
b2Vec2 C1( -sin(angle),cos(angle));
b2Vec2 C2(cos(angle),sin(angle));
b2Mat22 ROTMATRIX(C2,C1);
b2Vec2 End1 = e->GetVertex1();
b2Vec2 End2 = e->GetVertex2();
End1 = b2Mul(ROTMATRIX,End1);
End2 = b2Mul(ROTMATRIX,End2);
glColor4f(0.0,1.0,0.0,0.2);
b2Vec2 V1vtl = 100*(End1-CLight.centre);
b2Vec2 V2vtl = 100*(End2-CLight.centre);
glColor4f(0.0,0.0,0.0,1.0);
glBegin(GL_POLYGON);
glVertex3f(End1.x,End1.y,0.0);
glVertex3f(End2.x,End2.y,0.0);
glVertex3f(End2.x+V2vtl.x,End2.y+V2vtl.y,0.0);
glVertex3f(End1.x+V1vtl.x,End1.y+V1vtl.y,0.0);
glEnd();
}
void Box2dShadowEngine::RenderCircleShadow(void)
{
}
void Box2dShadowEngine::Render(b2World *world,float x, float y,bool Debug)
{
//glTranslatef(x,y,0);
DebugMode = Debug;
ShadowEngineWorld = world;
RenderLights();
RenderShadows();
}
.h (header) file
#pragma once
#include "GLOBAL.h"
using namespace std;
struct Light
{
public:
Light(void);
Light(float x, float y, float Radius);
void SetColour(float Red, float Green, float Blue,float Brightness);
void Move(float x, float y);
void Resize(float Radius);
float radius;
b2Vec2 centre;
float red;
float green;
float blue;
float brightness;
};
class Box2dShadowEngine
{
public:
Box2dShadowEngine(void);
~Box2dShadowEngine(void);
void AddLight(Light aLight);
void PrintLightList(void);
void Render(b2World *world,float x, float y,bool Debug);
void RenderLights(void);
void RenderShadows(void);
void RenderPolygonShadow(b2PolygonShape* p,b2Body* b,Light CLight);
void RenderCircleShadow(void);
void RenderLineShadow(b2EdgeShape* e,b2Body* b,Light CLight);
bool DebugMode;
b2World *ShadowEngineWorld;
vector<Light> LightList;
};
hope this helps, its kind of messy, but there are a couple of functions (render polygon shadow, and render line shadow in particular) which do most of the work.